package com.z.redis.command;

import com.z.redis.resp.BulkString;
import com.z.redis.resp.Resp;
import com.z.redis.resp.RespArray;
import com.z.redis.resp.SimpleString;
import com.z.redis.util.TRACEID;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

/**
 * 将Redis协议请求解析为具体的命令对象，实现命令的分发和执行
 */
public class CommandFactory {
    private static final Logger LOGGER = Logger.getLogger(CommandFactory.class);
    static Map<String, Supplier<Command>> map = new HashMap<>();
    // 遍历CommandType枚举，将枚举名作为key，枚举对象作为value，存入map中
    static {
        for (CommandType e : CommandType.values()) {
            map.put(e.name(), e.getSupplier());
        }
    }

    public static Command from(RespArray arrays){
        Resp[] array = arrays.getArray(); // 获取请求数组
        String commandName = ((BulkString) array[0]).getContent().toUTF8String().toLowerCase(); // 提取命令 转化成小写
        Supplier<Command> supplier = map.get(commandName); // 获取对应的命令生成器

        if(supplier == null){ // 如果不存在该命令
            LOGGER.debug("traceId:" + TRACEID.currentTraceId() + " 不支持的命令：" + commandName);
            System.out.println("不支持的命令：" + commandName);
            return null;
        } else { // 找到命令生成器
            try {
                Command command = supplier.get(); // 生成命令对象
                command.setContent(array); // 设置命令参数
                return command;
            } catch (Throwable e) {
                LOGGER.debug("traceId:" + TRACEID.currentTraceId() + " 不支持的命令：{},数据读取异常" + commandName);
                e.printStackTrace();
                return null;
            }
        }
    }

    /**
     * SimpleString，表示 Redis 协议的简单字符串格式（如 "PING"）
     * @param string
     * @return
     */
    public static Command from(SimpleString string){
        String commandName = string.getContent().toLowerCase(); // 提取命令 转化成小写
        Supplier<Command> supplier = map.get(commandName); // 获取对应的命令生成器

        if(supplier == null){ // 如果不存在该命令
            LOGGER.debug("traceId:" + TRACEID.currentTraceId() + " 不支持的命令：" + commandName);
            System.out.println("不支持的命令：" + commandName);
            return null;
        } else { // 找到命令生成器
            try {
                Command command = supplier.get(); // 生成命令对象
                return command;
            } catch (Throwable e) { // 创建失败
                LOGGER.debug("traceId:" + TRACEID.currentTraceId() + " 不支持的命令：{},数据读取异常" + commandName);
                e.printStackTrace();
                return null;
            }
        }
    }
}
